﻿// Decompiled with JetBrains decompiler
// Type: Microsoft.InfoCards.UIAgentAsyncBeginRequest
// Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// MVID: 8E14765A-6610-409A-BA36-099A0642905D
// Assembly location: E:\git\ALLIDA\windll\infocard.exe

using Microsoft.InfoCards.Diagnostics;
using Microsoft.Win32.SafeHandles;
using System;
using System.ComponentModel;
using System.IO;
using System.Text;
using System.Threading;

namespace Microsoft.InfoCards
{
  internal abstract class UIAgentAsyncBeginRequest : UIAgentRequest
  {
    private SafeWaitHandle m_agentEventHandle;
    private int m_asyncHandle;

    public UIAgentAsyncBeginRequest(
      IntPtr rpcHandle,
      Stream inArgs,
      Stream outArgs,
      ClientUIRequest parent)
      : base(rpcHandle, inArgs, outArgs, parent)
    {
    }

    protected override sealed void OnMarshalInArgs()
    {
      IntPtr zero = IntPtr.Zero;
      BinaryReader binaryReader = (BinaryReader) new InfoCardBinaryReader(this.InArgs, Encoding.Unicode);
      using (SafeWaitHandle hRemote = new SafeWaitHandle(Utility.ReadHandle(binaryReader), false))
        this.m_agentEventHandle = Utility.GetLocalHandleFromRemoteHandle(hRemote, this.ParentRequest.UIAgentPid);
      this.OnMarshalAsyncInArgs(binaryReader);
    }

    protected virtual void OnMarshalAsyncInArgs(BinaryReader reader)
    {
    }

    protected override void OnProcess()
    {
      AsyncParams asyncParams = this.CreateAsyncParams();
      asyncParams.AsyncResult.CancelCallback = new RpcAsyncResult.AsyncCancelCallback(this.AsyncCancel);
      InfoCardTrace.Assert(null != asyncParams, "Null AsyncParams");
      try
      {
        this.m_asyncHandle = asyncParams.AsyncResult.Handle;
        InfoCardTrace.Assert(0 != this.m_asyncHandle, "null async context handle");
        if (!ThreadPool.QueueUserWorkItem(InfoCardTrace.ThunkCallback(new WaitCallback(this.AsyncEntry)), (object) asyncParams))
          throw InfoCardTrace.ThrowHelperError((Exception) new CommunicationException(SR.GetString("UnableToQueueThreadpool")));
      }
      catch
      {
        asyncParams.AsyncResult.Dispose();
        throw;
      }
    }

    protected override void OnMarshalOutArgs()
    {
      BinaryWriter binaryWriter = new BinaryWriter(this.OutArgs, Encoding.Unicode);
      InfoCardTrace.Assert(0 != this.m_asyncHandle, "null async handle");
      binaryWriter.Write(this.m_asyncHandle);
    }

    protected override void OnDisposeAsUser()
    {
      if (this.m_agentEventHandle == null)
        return;
      this.m_agentEventHandle.Dispose();
      this.m_agentEventHandle = (SafeWaitHandle) null;
    }

    protected virtual AsyncParams CreateAsyncParams()
    {
      AsyncParams asyncParams = (AsyncParams) new UIAgentAsyncParams(this.GetType().Name, (ClientRequest) this.ParentRequest, this.m_agentEventHandle, (UIAgentRequest) this);
      this.m_agentEventHandle = (SafeWaitHandle) null;
      return asyncParams;
    }

    protected abstract object AsyncExecute(AsyncParams asyncParam);

    protected abstract void AsyncCancel();

    private void AsyncEntry(object state)
    {
      AsyncParams asyncParam = (AsyncParams) state;
      try
      {
        if (asyncParam.AsyncResult.IsCanceled)
          asyncParam.AsyncResult.Exception = (Exception) new Win32Exception(1223);
        else
          asyncParam.AsyncResult.Result = this.AsyncExecute(asyncParam);
      }
      catch (Exception ex)
      {
        if (InfoCardTrace.IsFatal(ex))
          InfoCardService.Crash(ex);
        asyncParam.AsyncResult.Exception = ex;
      }
      asyncParam.AsyncResult.Complete();
    }
  }
}
